/**
  ******************************************************************************
  * @file    led_blink.c
  * @author  ashuai0110
  * @version V2.0
  * @date    2024-09-03
  * @brief   LED闪烁状态机
  *
  ******************************************************************************
  * @attention
  *
  * 版权声明:内容为编者(ashuai0110)原创,使用请注明出处,当然,你也可以不这样做^_^
  * 出处链接:https://gitee.com/ashuai0110/mcu_reuse_development_module.git
  *
  * Change Logs:
  * Date          Author        Notes
  * 2024-08-15    ashuai0110    完成基本内容
  * 2024-09-03    ashuai0110    修改例程错误
  *
  ******************************************************************************
  */

/* 包含头文件-----------------------------------------------------------------*/
#include "led_blink.h"

#include "bsp.h"

/* 私有宏定义-----------------------------------------------------------------*/
#define LED_BLINK_INIT_TIME                         (500u)  /* 初始闪烁时间500ms*/
#define LED_BLINK_MAX_TIME                          (2000u) /* 闪烁最大时间2000ms*/
#define LED_BLINK_MIN_TIME                          (100u)  /* 闪烁最小时间100ms*/

/* 私有类型定义---------------------------------------------------------------*/

/* 私有变量-------------------------------------------------------------------*/

/* 全局变量-------------------------------------------------------------------*/

/* 私有函数原型---------------------------------------------------------------*/


/**
  * @brief  LED闪烁状态机构造函数
  *
  * @param  _fsm  : FSM实例化对象
  *
  * @retval None
  */
void led_blink_ctor(led_blink_fsm_t *_fsm)
{
    /* 调用fsm_ctor()以完成状态机的初始构造 */
    fsm_ctor(&_fsm->super, (fsm_state_handler_t)led_blink_initial);
}

/**
  * @brief  LED闪烁状态机初始转换函数
  *
  * @param  _fsm            : FSM实例化对象
  *
  * @param  event           : FSM事件
  *
  * @retval 返回处理状态 @ref fsm_ret_value
  *    @arg FSM_RET_HANDLED : 已处理
  *    @arg FSM_RET_IGNORED : 忽视
  *    @arg FSM_RET_TRAN    : 状态被转换
  */
uint8_t led_blink_initial(led_blink_fsm_t *_fsm, fsm_event_t const *event)
{
    (void)event;
    /* 此处完成状态机参数的初始化 */
    _fsm->blinkTime = LED_BLINK_INIT_TIME;
    _fsm->curTime = 0;
    /* 调用FSM_TRAN()以完成状态机的初始状态转换 initial->setting */
    return FSM_TRAN(led_blink_setting);
}

/**
  * @brief  LED闪烁状态机设置状态处理函数
  *
  * @param  _fsm            : FSM实例化对象
  *
  * @param  event           : FSM事件
  *
  * @retval 返回处理状态 @ref fsm_ret_value
  *    @arg FSM_RET_HANDLED : 已处理
  *    @arg FSM_RET_IGNORED : 忽视
  *    @arg FSM_RET_TRAN    : 状态被转换
  */
uint8_t led_blink_setting(led_blink_fsm_t *_fsm, fsm_event_t const *event)
{
    switch(event->signal)
    {
        case FSM_SIG_ENTRY: /* FSM的保留信号:进入信号 */
            MW_DEBUG_LOG("setting : fsm signal - entry");
            return FSM_HANDLED();
        
        case FSM_SIG_EXIT: /* FSM的保留信号:退出信号 */
            MW_DEBUG_LOG("setting : fsm signal - exit");
            return FSM_HANDLED();
        
        case LED_BLINK_SIG_UP: /* LED闪烁状态机的信号:时间增加信号 */
            if(LED_BLINK_MAX_TIME > _fsm->blinkTime)
            {
                _fsm->blinkTime += 100;
                MW_DEBUG_LOG("led blink time increase 100ms, current time %dms", _fsm->blinkTime);
            }
            MW_DEBUG_LOG("setting : led blink signal - up");
            return FSM_HANDLED();
        
        case LED_BLINK_SIG_DOWN: /* LED闪烁状态机的信号:时间减少信号 */
            if(LED_BLINK_MIN_TIME < _fsm->blinkTime)
            {
                _fsm->blinkTime -= 100;
                MW_DEBUG_LOG("led blink time reduce 100ms, current time %dms", _fsm->blinkTime);
            }
            MW_DEBUG_LOG("setting : led blink signal - down");
            return FSM_HANDLED();
        
        case LED_BLINK_SIG_OK: /* LED闪烁状态机的信号:确认信号 */
            MW_DEBUG_LOG("led blink time %dms, start blink now", _fsm->blinkTime);
            MW_DEBUG_LOG("setting : led blink signal - ok");
            /* 调用FSM_TRAN()以完成状态机的状态转换 setting->running */
            return FSM_TRAN(led_blink_running);
    }
    
    return FSM_IGNORED();
}

/**
  * @brief  LED闪烁状态机运行状态处理函数
  *
  * @param  _fsm            : FSM实例化对象
  *
  * @param  event           : FSM事件
  *
  * @retval 返回处理状态 @ref fsm_ret_value
  *    @arg FSM_RET_HANDLED : 已处理
  *    @arg FSM_RET_IGNORED : 忽视
  *    @arg FSM_RET_TRAN    : 状态被转换
  */
uint8_t led_blink_running(led_blink_fsm_t *_fsm, fsm_event_t const *event)
{
    switch(event->signal)
    {
        case FSM_SIG_ENTRY: /* FSM的保留信号:进入信号 */
            MW_DEBUG_LOG("running : fsm signal - entry");
            return FSM_HANDLED();
        
        case FSM_SIG_EXIT: /* FSM的保留信号:退出信号 */
            _fsm->curTime = 0;
            MW_DEBUG_LOG("running : fsm signal - exit");
            return FSM_HANDLED();
        
        case LED_BLINK_SIG_OK: /* LED闪烁状态机的信号:确认信号 */
            bsp_led_off(); /* 熄灭LED */
            MW_DEBUG_LOG("stop blink now, entry setting", _fsm->blinkTime);
            MW_DEBUG_LOG("running : led blink signal - ok");
            /* 调用FSM_TRAN()以完成状态机的状态转换 running->setting */
            return FSM_TRAN(led_blink_setting);
        
        case LED_BLINK_SIG_TICK: /* LED闪烁状态机的信号:100ms定时信号 */
            _fsm->curTime += 100;
            if(_fsm->curTime == _fsm->blinkTime)
            {
                _fsm->curTime = 0;
                bsp_led_toggle(); /* 闪烁LED */
                MW_DEBUG_LOG("led blink, current tick %d", ((led_blink_event_t *)event)->tick);
            }
            MW_DEBUG_LOG("running : led blink signal - tick");
            return FSM_HANDLED();
    }
    
    return FSM_IGNORED();
}
